﻿using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using PhiStore.Threading;

namespace PhiStore
{
    class Broadcaster : Boostable
    {
        private Channel<BroadcastObject> inputChannel;
        private IPEndPoint endpoint;
        private UdpClient udp;
        private BinaryFormatter formatter;
        private int interval = 5;

        public Broadcaster(Channel<BroadcastObject> inputChannel, int broadcastPort, int interval)
        {
            this.inputChannel = inputChannel;

            IPAddress multicastaddress = IPAddress.Parse("239.123.123.123");

            this.endpoint = new IPEndPoint(multicastaddress, broadcastPort);
            this.udp = new UdpClient(AddressFamily.InterNetwork);
            this.udp.JoinMulticastGroup(multicastaddress, 50);
            this.formatter = new BinaryFormatter();
            this.interval = interval;
        }

        public void Run()
        {
            try
            {
                BroadcastObject broadcastme = inputChannel.Receive();

                while (true)
                {
                    MemoryStream stream = new MemoryStream();
                    if (inputChannel.Count > 0 || inputChannel.IsPoisoned)
                    {
                        broadcastme = inputChannel.Receive();
                    }

                    formatter.Serialize(stream, broadcastme);

                    stream.Flush();

                    byte[] bytes = new byte[stream.Length];
                    stream.Position = 0;
                    stream.Read(bytes, 0, (int)stream.Length);
                    udp.Send(bytes, bytes.Length, endpoint);
                    stream.SetLength(0L);
                    stream.Close();

                    Log.Instance.Beep();

                    Thread.Sleep(interval * 1000);
                }
            }
            catch (PoisonException)
            {
                udp.Close();
                //bye bye
            }
        }
    }
}
